package com.lin.manager.oss.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.crypto.digest.MD5;
import com.lin.manager.oss.model.Chunk;
import com.lin.manager.oss.service.IOssBiz;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * @author linjiang
 * @date 2024/8/1
 * @fn
 */
@Service
public class OssBiz implements IOssBiz {
    private final static String ROOT = System.getProperty("user.dir") + "/doc/temp";

    @Override
    public Boolean uploadChunk(Chunk chunk) throws IOException {
        // 文件md5。同一个文件的md5值相同。不在于文件名是否同与不同
        File f = new File(ROOT, chunk.getMd5());
        if (!f.exists()) {
            f.mkdirs();
        }

        // 文件分片内容的md5
        String md5 = MD5.create().digestHex(chunk.getFile().getInputStream());
        File ff = new File(f, chunk.getChunk() + "-" + md5 + ".part");

        if (ff.exists()) {
            System.out.println("文件秒传");
            return true;
        }

        // 分片上传
        try (RandomAccessFile accessFile = new RandomAccessFile(ff, "rw")) {
            accessFile.write(chunk.getFile().getBytes());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public void merge(Chunk chunk) {
        File f = new File(ROOT, chunk.getMd5());
        if (f.exists()) {
            List<File> list = new ArrayList<>();

            File[] files = f.listFiles();
            for (int i = 0; i < files.length; i++) {
                int temp = i;
                Optional<File> optional = Arrays.stream(files).filter(file -> file.getName().startsWith("" + temp)).findFirst();
                list.add(optional.get());
            }

            try (FileOutputStream outputStream = new FileOutputStream(new File(f, chunk.getName()))) {
                for (File shardFile : files) {
                    FileUtil.writeToStream(shardFile, outputStream);

                    // 删除分片
                    shardFile.delete();
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
